fix(session): don't clobber user's model swap on model-less prompts - #42894
fix(session): don't clobber user's model swap on model-less prompts#42894Qiiks wants to merge 1 commit into
Conversation
A model-less prompt (no input.model — e.g. plugin completion-reminders via promptAsync) resolves from the agent fallback (ag.model) for the turn. The existing design (PR anomalyco#26765) intentionally uses the agent's model when no explicit model is given. However, setAgentModel then overwrites the session row to the resolved model, permanently destroying a model the user explicitly stored via a prior swap. The TUI is unaffected (always sends draft.model explicitly), but opencode serve / mobile clients lose the swap on the next plugin reminder. Guard the setAgentModel write: skip it when the prompt carried no explicit model AND the session already has a stored model that differs from the agent's resolved model. Fresh sessions (no stored model) and explicit-model prompts still persist normally.
|
This seems to fix the original model-clobber case, but I found a related state-update edge case: the guard can also suppress an explicit agent change because Consider this sequence:
The PR correctly prevents fallback model However, because
rather than:
In this case the two fields need different treatment: preserve the stored model, but still persist the explicitly selected agent. I think a regression covering this transition would be useful:
That would preserve the model-swap fix without leaving the persisted agent stale. |
|
Issue for this PR
Closes #42893
Type of change
What does this PR do?
A model-less prompt (no
input.model— e.g. plugin completion-reminders viapromptAsync) resolves from the agent fallback (ag.model) for the turn. The existing design (PR #26765) intentionally uses the agent's model when no explicit model is given — this is correct for the turn's model and is preserved.However,
setAgentModelthen overwrites the session row to the resolved model, permanently destroying a model the user explicitly stored via a prior swap. The TUI is unaffected (always sendsdraft.modelexplicitly), butopencode serve/ mobile clients lose the swap on the next plugin reminder.The fix: guard the
setAgentModelwrite increateUserMessage— skip it when:input.model == null), ANDstoredModelDiffers)Fresh sessions (no stored model) still persist the agent's model on the first model-less prompt (
hasNoStoredModelguard), and explicit-model prompts always persist normally. The model-resolution precedence is unchanged — model-less prompts still use the agent's model for the turn.How did you verify your code works?
"model-less prompt does not clobber user's stored model swap"— creates a session, swaps tokimi-k2.5-free, sends a model-less prompt with an agent carryingtest/test-model, asserts the turn usestest-model(design preserved) but the session row stayskimi-k2.5-free(the fix). Verified RED→GREEN."model-less first prompt on fresh session persists agent model to row"— confirms thehasNoStoredModelguard firessetAgentModelon a fresh session so the row is initialized."applies agent variant only when using agent model"(the test that pins the agent-model design from Persist session model switches outside event flag #26765) still passes — model-less prompts still use the agent's model for the turn.test/session/prompt.test.ts.Checklist